#! /usr/bin/python3

import json
import time
from datetime import datetime

import paho.mqtt.client as mqtt
from sqlalchemy import event
from sqlalchemy.orm import Session
from socket import error as socket_error
from service.data import Data

m_type = {'jg': '加工', 'tb': '涂装半成品', 'tc': '涂装成品', 'yr': '亚克力入口', 'yc': '亚克力出口',
          'xy': '旋压', 'xy2': '旋压2', 'qm': '切帽', 'zm': '正面', 're1': '热处理1线', 're2': '热处理2线',
          'zz1': '铸造1线', 'zz2': '铸造2线', 'zz3': '铸造2线边浇', 'ng': '加工_分立', 'njg': 'F2加工_分立',
          're3': 'F2热处理'}
m_type_exclude = ['re1', 're2', 'zz1', 'zz2', 'zz3', 'ng', 'njg', 're3']
# 1_2线铸造
m_type_2 = {'esp8266_B41141': '铸造1线'}
week = ('一', '二', '三', '四', '五', '六', '天')
_FACTORY_1 = 1
_FACTORY_2 = 2


class Logger:
    def __init__(self, session, socketio):
        # db
        self.Session = session
        # 临时变量
        self.temp = {}
        # 临时变量 zz
        self.temp_zz = {}
        self.refresh = True
        # socketio
        self.socketio = socketio
        # mqtt
        client_id = 'client_' + str(datetime.now())
        self.client = mqtt.Client(protocol=3)
        # self.client = mqtt.Client(client_id=client_id.replace(':', '-').replace(' ', '-'), clean_session=True,
        #                          userdata=None, protocol=3,
        #                          transport="tcp")
        self.client.on_connect = self.on_connect
        self.client.on_message = self.on_message
        self.client.on_disconnect = self.on_disconnect
        # 压力历史值 2019.06.19
        self.history_pressure_1 = []
        self.history_pressure_2 = []

    @staticmethod
    def on_connect(client, userdata, flags, rc):
        print("Connected mqtt, result: " + str(rc))
        client.subscribe([("c/#", 0), ("c2/#", 0), ("c2/#", 0), ("pressure/#", 0)])
        # client.subscribe("c2/#", 1)
        # 1-2
        # self.client.subscribe("/xy/#")
        # 压力 2019.06.19
        # result, _ = self.client.subscribe("pr/#")
        # print('订阅压力topic:', result)

    def on_disconnect(self):
        print('睡眠10秒')
        time.sleep(10)
        print('重连')
        self.connect_mqtt()

    # mqtt消息到达
    def on_message(self, client, userdata, message):
        data = json.loads(message.payload)
        print(message.topic, data)
        t = message.topic.split('/')
        factory = _FACTORY_1
        if t[0] == 'c2':  # 工厂2
            factory = _FACTORY_2
        # 1_2
        if t[1] == 'xy' and 'events' in t:
            # self.save_data_2(data, factory)
            pass
        else:
            self.save_data(message.topic, data, factory)
        # print(msg.topic + " " + str(msg.payload))

        # 压力值，存储到队列 2019.06.19
        if t[0] == 'pressure':
            print('我在这里')
            print(data['pressure'])
            if message.payload['device'] == 'Line2':
                if len(self.history_pressure_2) > 10:
                    self.history_pressure_2.pop(0)
                self.history_pressure_2.append(data['device'] + ' ' + data['pressure'])

    # 连接mqtt
    def connect_mqtt(self):
        try:
            self.client.connect("127.0.0.1", 1883, 10)
        except (TimeoutError, socket_error) as e:
            print('连接超时')
            print('睡眠10秒')
            time.sleep(10)
            self.connect_mqtt()
        else:
            self.client.loop_forever()

    # 监听数据变化
    @event.listens_for(Session, 'after_commit')
    def update_index(self, session):
        print('ok')

    def save_data(self, topic, json, factory):
        # zero
        self.temp.clear()
        # 主题检查
        _, topic_class, _ = topic.split('/')
        d = json['d']
        ts = datetime.strptime(json['ts'], '%Y-%m-%dT%H:%M:%S.%f')
        c_date = "%d.%02d.%02d %02d:%02d 星期%s" % (
            ts.year, ts.month, ts.day, ts.hour, ts.minute, week[ts.weekday()])
        is_daytime = False
        if 7 <= datetime.now().hour < 19:  # 白/晚班判断
            is_daytime = True

        # 7点 白班 夜班交替 刷新页面1次
        if ts.hour == 7:
            if self.refresh:
                self.socketio.emit('refresh', True)
                self.refresh = False
        else:
            if not self.refresh:
                self.refresh = True

        # 时间
        if 'tm' in d:  # 使用plc时间
            tm = datetime.strptime(
                '20%d-%d-%d %d:%d:%d' % (d['tm'][0], d['tm'][1], d['tm'][2], d['tm'][3], d['tm'][4], d['tm'][5]),
                '%Y-%m-%d %H:%M:%S')
        else:
            tm = ts

        session = self.Session()
        if topic_class in m_type_exclude:
            # print('主题分类：', topic_class)
            try:
                type = m_type[topic_class]
                data = Data(number=d['yc'][0], ts=tm, type=type, factory=factory)
                session.add(data)
            except Exception as e:
                print(e)
            # 存入temp
            self.temp[topic_class] = d['yc'][0]
        else:
            for k, v in d.items():
                if k == 'tm' or k == 'tm2':
                    continue
                try:
                    type = m_type[k]
                    data = Data(number=v[0], ts=tm, type=type, factory=factory)
                    session.add(data)
                    # 存入temp
                    self.temp[k] = v[0]
                except:
                    continue

        session.commit()
        session.close()
        # emmit
        self.temp['date'] = c_date
        self.temp['is_daytime'] = is_daytime
        self.temp['factory'] = factory
        # print('db:' + str(self.temp))  # debug
        # 直接发送变量值
        self.socketio.emit('index_data', self.temp)

    # 2
    def save_data_2(self, json, factory):
        # zero
        self.temp.clear()
        d = json
        try:
            ts = datetime.strptime(d['t'], '%Y-%m-%d %H:%M:%S')
        except:
            print('日期格式错误:%s' % d['t'])
            return
        c_date = "%d.%02d.%02d %02d:%02d 星期%s" % (
            ts.year, ts.month, ts.day, ts.hour, ts.minute, week[ts.weekday()])
        is_daytime = False
        if 7 <= datetime.now().hour < 19:  # 白/晚班判断
            is_daytime = True

        # 7点 白班 夜班交替 刷新页面1次
        if ts.hour == 7:
            if self.refresh:
                self.socketio.emit('zz_refresh', True)
                self.refresh = False
        else:
            if not self.refresh:
                self.refresh = True

        # 时间
        tm = datetime.strptime(d['t'],
                               '%Y-%m-%d %H:%M:%S')
        # 消息：{"num":173,"t":"2018-08-19 10:40:31","id":"esp8266_B40F4D"}
        session = self.Session()
        try:
            data = Data(number=d['num'], ts=tm, type=m_type_2[d['id']], factory=factory)
            session.add(data)
            # 存入temp
            if d['id'] == 'esp8266_B41141':
                self.temp_zz['zz_1'] = d['num']
        except Exception as e:
            print(e)

        session.commit()
        session.close()
        # emmit
        self.temp_zz['date'] = c_date
        self.temp_zz['is_daytime'] = is_daytime
        self.temp_zz['factory'] = factory
        print('db_zz:' + str(self.temp_zz))  # debug
        # 直接发送变量值
        self.socketio.emit('zz_data', self.temp_zz)

    def get_temp(self):
        return self.temp

    # 返回压力历史数据
    def get_history_pressure(self):
        return self.history_pressure_2


if __name__ == '__main__':
    logger = Logger(Session, None)
    logger.connect_mqtt()
